package ch.kerbtier.webglue;

import groovy.lang.Binding;
import groovy.lang.GroovyClassLoader;
import groovy.lang.Script;

import java.io.File;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

import org.codehaus.groovy.control.CompilationFailedException;

public class GroovyNonReloadable implements CodeRunner {
	private String path;
	private Map<String, Class> classes = new HashMap<String, Class>();

	public GroovyNonReloadable(String path) {
		this.path = path;
	}

	public Object run(String name, Map<String, Object> parameters) {
		final Binding binding = new Binding();
		for (String key : parameters.keySet()) {
			binding.setVariable(key, parameters.get(key));
		}

		binding.setVariable("script", new Object() {
			public Object evaluate(String name) {
				return run(name, binding);
			}
		});
		return run(name, binding);
	}

	public Object run(String name, Binding binding) {
		Class klass = null;
		if (classes.containsKey(name)) {
			klass = classes.get(name);
		} else {

			ClassLoader parent = getClass().getClassLoader();
			GroovyClassLoader loader = new GroovyClassLoader(parent);
			try {
				// if file is not absolute, add path in front
				File f = new File(name);
				if (!f.isAbsolute()) {
					f = new File(path, name);
				}

				klass = loader.parseClass(f);
				classes.put(name, klass);
			} catch (CompilationFailedException e) {
				classes.put(name, null);
				e.printStackTrace();
			} catch (IOException e) {
				classes.put(name, null);
				e.printStackTrace();
			}
		}

		Script script;
		if (klass != null) {
			try {
				script = (Script) klass.newInstance();
				script.setBinding(binding);
				return script.run();
			} catch (InstantiationException e) {
				e.printStackTrace();
			} catch (IllegalAccessException e) {
				e.printStackTrace();
			}
		}
		return null;
	}
}
